package com.xiyuan.smartutils;

import com.xiyuan.smartutils.constants.SignConstants;
import com.xiyuan.smartutils.reflect.Unsafe;

import java.text.DecimalFormat;

/**
 * 数学相关工具类
 *
 * @version v1.0.0 @author lgz 2017-8-27 新建与整理
 */

public final class Maths implements SignConstants {
    static {
        Unsafe.init();
    }
    private Maths() {}
    
    private static final int PERMIL_VALUE = 1000;
    
    /**
     * 提供被除数，除数和小数位数，得到结果
     *
     * @param dividend 被除数，字符串格式
     * @param divisor  除数
     * @param radixLen 小数位数
     * @return String 结果
     */
    public static String division(String dividend, long divisor, int radixLen) {
        long dividendLong = Long.parseLong(dividend);
        return division(dividendLong, divisor, radixLen);
    }
    
    /**
     * 提供被除数，除数和小数位数，得到结果
     *
     * @param dividend 被除数，数值格式
     * @param divisor  除数
     * @param radixLen 小数位数
     * @return String 结果
     */
    public static String division(long dividend, long divisor, int radixLen) {
        if (radixLen <= 0) {return String.valueOf(dividend / divisor);}
        
        double result = (double) dividend / divisor;
        StringBuilder radix = new StringBuilder("#");
        if (radixLen > 0) {
            radix.append(".");
            for (int i = 0; i < radixLen; i++) {radix.append(_SHARP_);}
        }
        
        DecimalFormat df = new DecimalFormat(radix.toString());
        StringBuilder ret = new StringBuilder(df.format(result));
        
        if (radixLen > 0) {
            int ind = ret.toString().indexOf('.');
            if (ind == -1) {
                //没有小数点
                ret.append(".");
                for (int i = 0; i < radixLen; i++) {ret.append(0);}
            }
            else if (ind > ret.length() - radixLen - 1) {
                //小数位数不足,尾部加0
                int zeroNum = ind - (ret.length() - radixLen - 1);
                for (int i = 0; i < zeroNum; i++) {
                    ret.append("0");
                }
            }
        }
        
        return ret.toString();
    }
    
    /**
     * 对整数增加千分号后，转为字符串，如32323211转为32,323,211
     *
     * @param value 整数，如：32323211
     * @return 加千分号的字符串，如：32,323,211
     */
    public static String permil(long value) {
        StringBuilder strb = new StringBuilder();
        while (value >= PERMIL_VALUE) {
            long remainder = value % PERMIL_VALUE;
            value = value / PERMIL_VALUE;
            
            strb.insert(0, StrUtils.prefixZero(remainder, 3));
            strb.insert(0, ",");
        }
        
        strb.insert(0, value);
        return strb.toString();
    }
    
    /**
     * 对文件大小进行K/M/G处理，保留指定小数位数
     *
     * @param value    大小值
     * @param radixLen 小数位数
     * @return 转为K/M/G的小数值
     */
    public static String size(long value, int radixLen) {
        if (value < KiB) {
            return value + "B";
        }
        else if (value < MiB) {
            return division(value, KiB, radixLen) + "K";
        }
        else if (value < GiB) {
            return division(value, MiB, radixLen) + "M";
        }
        else if (value < TiB) {
            return division(value, GiB, radixLen) + "G";
        }
        else if (value < PiB) {
            return division(value, TiB, radixLen) + "T";
        }
        else if (value < EiB) {
            return division(value, PiB, radixLen) + "P";
        }
        else {
            return division(value, EiB, radixLen) + "E";
        }

//        else if (value < ZiB) {
//            return division(value, EiB, radixLen) + "E";
//        }
//        else if (value < YiB) {
//            return division(value, ZiB, radixLen) + "Z";
//        }
//        else {
//            return division(value, YiB, radixLen) + "Y";
//        }
    }
}
